import numpy as np
TOL = 0.001
r3 = np.sqrt(3.)
A = np.array([\
 [           1,        1./3,        1./3,        1./3,          -2./3,           4./3], ### m1
 [           1,        1./3,       -1./3,       -1./3,          -2./3,           4./3],
 [           1,        2-r3,    (2*r3-3),        1/r3,           1-r3,           3-r3],
 [           1,        2-r3,   -(2*r3-3),       -1/r3,           1-r3,           3-r3],
 [           1,    1/(3+r3),        1/r3,    (r3-1)/2,      -1/(3-r3),  (4+r3)/(3+r3)],
 [           1,    1/(3+r3),       -1/r3,   -(r3-1)/2,      -1/(3-r3),  (4+r3)/(3+r3)],
 [           1,   -1/(3+r3),        1/r3,   -(r3-1)/2, -(4+r3)/(3+r3),       1/(3-r3)],
 [           1,   -1/(3+r3),       -1/r3,    (r3-1)/2, -(4+r3)/(3+r3),       1/(3-r3)],
 [           1,        r3-2,    (2*r3-3),       -1/r3,           r3-3,           r3-1],
 [           1,        r3-2,   -(2*r3-3),        1/r3,           r3-3,           r3-1],
 [           1,       -1./3,        1./3,       -1./3,          -4./3,           2./3],
 [           1,       -1./3,       -1./3,        1./3,          -4./3,           2./3],
 [ -(2*r3-6)/3, -(2*r3-4)/3,  (2*r3-2)/3,        2./3,          -2./3,           4./3],
 [ -(2*r3-6)/3,  (2*r3-4)/3, -(2*r3-2)/3,       -2./3,          -2./3,           4./3],
 [ -(2*r3-6)/3, -(2*r3-4)/3,  (2*r3-2)/3,        2./3,          -4./3,           2./3],
 [ -(2*r3-6)/3,  (2*r3-4)/3, -(2*r3-2)/3,       -2./3,          -4./3,           2./3],
 [        r3-1,   -(r3-3)/3,   -(r3-3)/3,      (r3-1),     (2*r3-6)/3,           2/r3],
 [        r3-1,    (r3-3)/3,    (r3-3)/3,     -(r3-1),     (2*r3-6)/3,           2/r3],
 [        r3-1,   -(r3-3)/3,   -(r3-3)/3,     -(r3-1),          -2/r3,    -(2*r3-6)/3],
 [        r3-1,    (r3-3)/3,    (r3-3)/3,      (r3-1),          -2/r3,    -(2*r3-6)/3], ### #TODO check r3-1, last line col 4 #     check 2r3-3 in m1_3,3 
 [        2./3,        2./3,           0,           0,          -2./3,           4./3], ### m2
 [        2./3,       -2./3,           0,           0,          -4./3,           2./3],
 [    (3-r3)/3,    (r3-1)/3,    (r3+1)/3,   -(r3-1)/3,          -4./3,           2./3],
 [    (3-r3)/3,   -(r3-1)/3,   -(r3+1)/3,    (r3-1)/3,          -4./3,           2./3],
 [    (3-r3)/3,    (r3-1)/3,    (r3+1)/3,    (r3-1)/3,          -2./3,           4./3],
 [    (3-r3)/3,   -(r3-1)/3,   -(r3+1)/3,   -(r3-1)/3,          -2./3,           4./3],
 [  (4*r3-6)/3, -(4*r3-8)/3,  (4*r3-4)/3,  (2*r3-4)/3,          -4./3,           2./3],
 [  (4*r3-6)/3, -(4*r3-8)/3, -(4*r3-4)/3, -(2*r3-4)/3,          -4./3,           2./3],
 [  (4*r3-6)/3,  (4*r3-8)/3,  (4*r3-4)/3, -(2*r3-4)/3,          -2./3,           4./3],
 [  (4*r3-6)/3,  (4*r3-8)/3, -(4*r3-4)/3,  (2*r3-4)/3,          -2./3,           4./3],
 [     -(r3-2),     -(r3-2),           1, -(2*r3-3)/3,          (r3-3),        (r3-1)],
 [     -(r3-2),     -(r3-2),          -1,  (2*r3-3)/3,          (r3-3),        (r3-1)],
 [     -(r3-2),      (r3-2),           1, -(2*r3-3)/3,         -(r3-1),       -(r3-3)],
 [     -(r3-2),      (r3-2),          -1,  (2*r3-3)/3,         -(r3-1),       -(r3-3)],
 [           0,           1,           0,        1/r3,              -1,             1],
 [           0,           1,           0,       -1/r3,              -1,             1],
 [           0,        2./3,        2./3,  (2*r3-2)/3,           -4./3,          2./3],
 [           0,        2./3,        2./3, -(2*r3-2)/3,           -4./3,          2./3],
 [           0,        2./3,           0,        2/r3,           -4./3,          2./3],
 [           0,        2./3,           0,       -2/r3,           -4./3,          2./3], ###
 [           0,        2./3,       -2./3,  (2*r3-2)/3,           -4./3,          2./3], ### m3
 [           0,        2./3,       -2./3, -(2*r3-2)/3,           -4./3,          2./3],
 [           0,   -(2*r3-4),    (4*r3-6),           0,         -(r3-2),     -(2*r3-4)],
 [           0,   -(2*r3-4),   -(4*r3-6),           0,         -(r3-2),     -(2*r3-4)],
 [           0,    (2*r3-4),    (4*r3-6),           0,        (2*r3-4),        (r3-2)],
 [           0,    (2*r3-4),   -(4*r3-6),           0,        (2*r3-4),        (r3-2)],
 [           0,       -2./3,        2./3,  (2*r3-2)/3,           -2./3,          4./3],
 [           0,       -2./3,        2./3, -(2*r3-2)/3,           -2./3,          4./3],
 [           0,       -2./3,           0,        2/r3,           -2./3,          4./3],
 [           0,       -2./3,           0,       -2/r3,           -2./3,          4./3],
 [           0,       -2./3,       -2./3,  (2*r3-2)/3,           -2./3,          4./3],
 [           0,       -2./3,       -2./3, -(2*r3-2)/3,           -2./3,          4./3],
 [           0,          -1,           0,        1/r3,              -1,             1],
 [           0,          -1,           0,       -1/r3,              -1,             1],
 [      (r3-2),     -(r3-2),           1,    (2/r3-1),          (r3-3),        (r3-1)],
 [      (r3-2),     -(r3-2),          -1,   -(2/r3-1),          (r3-3),        (r3-1)],
 [      (r3-2),      (r3-2),           1,   -(2/r3-1),         -(r3-1),       -(r3-3)],
 [      (r3-2),      (r3-2),          -1,    (2/r3-1),         -(r3-1),       -(r3-3)],
 [ -(4*r3-6)/3, -(4*r3-8)/3,  (4*r3-4)/3, -(2*r3-4)/3,           -4./3,          2./3],
 [ -(4*r3-6)/3, -(4*r3-8)/3, -(4*r3-4)/3,  (2*r3-4)/3,           -4./3,          2./3], ###
 [ -(4*r3-6)/3,  (4*r3-8)/3,  (4*r3-4)/3,  (2*r3-4)/3,           -2./3,          4./3], ### m4
 [ -(4*r3-6)/3,  (4*r3-8)/3, -(4*r3-4)/3, -(2*r3-4)/3,           -2./3,          4./3],
 [    (r3-3)/3,    (r3-1)/3,    (1+r3)/3,    (r3-1)/3,           -4./3,          2./3],
 [    (r3-3)/3,    (r3-1)/3,   -(1+r3)/3,   -(r3-1)/3,           -4./3,          2./3],
 [    (r3-3)/3,   -(r3-1)/3,    (1+r3)/3,   -(r3-1)/3,           -2./3,          4./3],
 [    (r3-3)/3,   -(r3-1)/3,   -(1+r3)/3,    (r3-1)/3,           -2./3,          4./3],
 [       -2./3,        2./3,           0,           0,           -2./3,          4./3],
 [       -2./3,       -2./3,           0,           0,           -4./3,          2./3],
 [        1-r3,   -(r3-3)/3,   -(r3-3)/3,     -(r3-1),      (2*r3-6)/3,          2/r3],
 [        1-r3,   -(r3-3)/3,    (r3-3)/3,      (r3-1),      (2*r3-6)/3,          2/r3],
 [        1-r3,    (r3-3)/3,   -(r3-3)/3,      (r3-1),           -2/r3,   -(2*r3-6)/3],
 [        1-r3,    (r3-3)/3,    (r3-3)/3,     -(r3-1),           -2/r3,   -(2*r3-6)/3],
 [  (2*r3-6)/3, -(2*r3-4)/3,  (2*r3-2)/3,       -2./3,           -2./3,          4./3],
 [  (2*r3-6)/3, -(2*r3-4)/3, -(2*r3-2)/3,        2./3,           -2./3,          4./3],
 [  (2*r3-6)/3,  (2*r3-4)/3,  (2*r3-2)/3,       -2./3,           -4./3,          2./3],
 [  (2*r3-6)/3,  (2*r3-4)/3, -(2*r3-2)/3,        2./3,           -4./3,          2./3],
 [          -1,        1./3,        1./3,       -1./3,           -2./3,          4./3],
 [          -1,        1./3,       -1./3,        1./3,           -2./3,          4./3],
 [          -1,        2-r3,    (2*r3-3),       -1/r3,            1-r3,          3-r3],
 [          -1,        2-r3,   -(2*r3-3),        1/r3,            1-r3,          3-r3], ###
 [          -1,    1/(r3+3),        1/r3,   -(r3-1)/2,        1/(r3-3), (r3+4)/(r3+3)], ### m5
 [          -1,    1/(r3+3),       -1/r3,    (r3-1)/2,        1/(r3-3), (r3+4)/(r3+3)],
 [          -1,   -1/(r3+3),        1/r3,   -(r3-1)/2,  -(r3+4)/(r3+3),     -1/(r3-3)],
 [          -1,   -1/(r3+3),       -1/r3,    (r3-1)/2,  -(r3+4)/(r3+3),     -1/(r3-3)],
 [          -1,      (r3-2),    (2*r3-3),        1/r3,          (r3-3),       -(r3-1)],
 [          -1,      (r3-2),   -(2*r3-3),       -1/r3,          (r3-3),       -(r3-1)],
 [          -1,       -1./3,        1./3,        1./3,           -4./3,          2./3],
 [          -1,       -1./3,       -1./3,       -1./3,           -4./3,          2./3],
 [           1,           0,           0,           0,              -1,             1],
 [           0,           1,           0,           0,              -1,             1],
 [           0,           0,           1,           0,              -1,             1]],
 dtype='float32')

def b1(t):
    t1 = t[0] 
    t2 = t[1]
    t1 = np.deg2rad(t1)
    t2 = np.deg2rad(t2)
    return (-np.cos(2*t1)+np.cos(2*t2))/2
def b2(t):
    t1 = t[0] 
    t2 = t[1]
    t1 = np.deg2rad(t1)
    t2 = np.deg2rad(t2)
    return (-np.cos(4*t1)+np.cos(4*t2))/2
def b3(t):
    t1 = t[0] 
    t2 = t[1]
    t1 = np.deg2rad(t1)
    t2 = np.deg2rad(t2)
    return (-np.sin(2*t1)+np.sin(2*t2))/2
def b4(t):
    t1 = t[0] 
    t2 = t[1]
    t1 = np.deg2rad(t1)
    t2 = np.deg2rad(t2)
    return (-np.sin(4*t1)+np.sin(4*t2))/2
import itertools
angles = [0,30,-30,45,-45,60,-60,90]
prmd = {\
          0:'a1',
          1:'a2',
          2:'a3',
          3:'a4',
          4:'b1',
          5:'b2',
          6:'b3',
          7:'b4',
          8:'d1',
          9:'d2',
         10:'d3',
         11:'d4',
         }
def check_params( params ):
    global A
    global prmd
    ind = range(12)
    prmlst = [params[prmd[i]] for i in ind]
    xla = np.array([ prmlst[ 0:4 ] + [-1, 0] ], dtype='float16').transpose()
    xua = np.array([ prmlst[ 0:4 ] + [ 0,-1] ], dtype='float16').transpose()
    xld = np.array([ prmlst[ 8:12] + [-1, 0] ], dtype='float16').transpose()
    xud = np.array([ prmlst[ 8:12] + [ 0,-1] ], dtype='float16').transpose()
    xb  = np.array([ prmlst[ 4:8 ] + [ 0, 0] ], dtype='float16').transpose()
    for i in range( 91 ):
        Ai = A[i]
        eql = Ai.dot(xla)**4 + 3*(Ai.dot(xb)**2) - 4*(Ai.dot(xla))*(Ai.dot(xld))
        if eql > TOL:
            print 'lower violated %2.3f' % eql,'line',i+1
            return False
            #break
        equ = Ai.dot(xua)**4 + 3*(Ai.dot(xb)**2) - 4*(Ai.dot(xua))*(Ai.dot(xud))
        if equ > TOL:
            print 'UPPER violated %2.3f' % equ,'line',i+1
            return False
            #break
    k = np.sqrt(3)/2
    a4 = prmlst[ 3]
    b4 = prmlst[ 7]
    d4 = prmlst[11]
    eq = (a4 + k)**4 + 3*k**2*b4**2 - 4*k**2*(a4+k)*(d4+k)
    if eq > TOL:
        print 'eql2 violated'
        return False
    eq = (a4 - k)**4 + 3*k**2*b4**2 - 4*k**2*(a4-k)*(d4-k)
    if eq > TOL:
        print 'equ2 violated'
        return False
    return True
